有一次在串接合作廠商的 API 時,需要把他原本取 token 的 javascript 改寫成 PHP 版;其中有一個步驟需要用 PHP 產生介於 0 到 1 之間的浮點數,看似簡單卻卡了我一陣子。
原因是 PHP 似乎沒有提供一個函式可以直接做到(有的話請告訴我>_<)
PHP 提供的亂數函式,會回傳一個整數,可以給訂一個範圍
rand(0,15); // 0 <= output <= 15
如果為給定範圍,會回傳一個 0 到 RAND_MAX 的隨機整數。
而 RAND_MAX 是多少呢?這會根據所使用系統而有所不同,可以透過 getrandmax()
得知。
getrandmax(); // output 2147483647,2的31次方減1,32位元有號整數的最大值
實作前要再確認是需求是哪種
可以用rand()除以最大值 RAND_MAX。
rand() / getrandmax(); // 0 <= output <= 1
但這做法理論上會包含 0 和 1,只是機率很小,保守一點可以做排除。
$rand = rand() / getrandmax();
while ($rand == 1 || $rand == 0) {
$rand = rand() / getrandmax();
}
另外分享一個另類的做法,就是用 sin()
,利用他會回傳一個 -1 到 1 浮點數的特性來做,以前做動畫常常會用到(茶)
感謝幫友提醒,這方法數值偏兩端(0 跟 1)的機率會比中間(0.5)的高
// 確實會產生介於 0 到 1 之間的數,但非平均分佈
(sin(rand())+1)/2;
注意,這邊 sin()
的輸入單位是弧度 (角度轉弧度)
//0 <= output < 1
rand() / (getrandmax() + 1);
//0 < output < 1
(rand() + 1) / (getrandmax() + 2);
另外用 sin
函數跑出來應該會不均勻吧?(sin(rand())+1)/2
數值偏兩端( 0跟 1)的機率會比中間(0.5)的高
阿對...會不平均...
感謝提醒!已補充在正文